package com.xiang.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class DeviceUpgradeUtils {

  //base64随机字符
  public static String BASE64 = "WJZHKTLIGIKNAUSQ";

  public static String privateKey = "tYS2QJqWhUmPN2FtXH0jEQ==";

  public static void main(String[] args) throws Exception {
    Long currentTime = System.currentTimeMillis();
    String secretKey = generateSecretKey();
    System.out.println(secretKey);
    getCaptcha(secretKey, currentTime, 600);

    /*JSONObject params = new JSONObject();
    Long currentTime = 1664183814L;
    String secretKey = "TGK5EKWLU7X65J33";
    params.put("currentTime", currentTime);
    params.put("secretKey", secretKey);
    params.put("time", 600);

    // System.out.println(AESUtil.generateKey(128));

    String content = params.toJSONString();
    System.out.println("原数据：" + content);

    String encrypt = AESUtil.encrypt(content, privateKey);
    System.out.println("加密内容：" + encrypt);
    String decrypt = AESUtil.decrypt(encrypt, privateKey);
    System.out.println("解密内容" + decrypt);*/
  }

  /**
   * 获取生成验证码
   * @return
   */
  public static String getCaptcha(){

    String captcha = null;
    try {
      String secretKey= generateSecretKey();
      Long currentTime = System.currentTimeMillis();
      // 1、获取MD5生成的秘钥
      String md5Key = md5GenerateKey(secretKey, currentTime, 300);
      // 2、取秘钥后4位
      md5Key = md5Key.substring(md5Key.length() - 4);
      // 3、将秘钥转换10进制
      captcha = String.valueOf(covert(md5Key));
      // 4、多余4位数字截取按4位返回
      if (captcha.length() > 4) {
        captcha = captcha.substring(captcha.length() - 4);
      }
      log.info("生成验证码成功：" + captcha);
    } catch (Exception e) {
      log.error("验证码生成失败：" + e.getMessage());
    }
    return captcha;


  }

  /**
   * 生成4位数字验证码.
   *
   * @param secretKey 随机密钥
   * @param time 时间内有效(s)
   */
  public static String getCaptcha(String secretKey, Long currentTime, int time) {
    String captcha = null;
    try {
      // 1、获取MD5生成的秘钥
      String md5Key = md5GenerateKey(secretKey, currentTime, time);
      if (StringUtils.isEmpty(md5Key)) {
        return null;
      }
      // 2、取秘钥后4位
      md5Key = md5Key.substring(md5Key.length() - 4, md5Key.length());
      if (StringUtils.isEmpty(md5Key)) {
        return null;
      }
      // 3、将秘钥转换10进制
      captcha = String.valueOf(covert(md5Key));
      if (StringUtils.isEmpty(captcha)) {
        return null;
      }
      // 4、多余4位数字截取按4位返回
      if (captcha.length() > 4) {
        captcha = captcha.substring(captcha.length() - 4, captcha.length());
      }
      log.info("生成验证码成功：" + captcha);
    } catch (Exception e) {
      log.error("验证码生成失败：" + e.getMessage());
    }
    return captcha;
  }

  /**
   * 使用MD5生成验证码.
   * 生成规则：时间戳+随机码+时间范围.
   * 取MD5后四位生成数字作为短信验证码.
   */
  public static String md5GenerateKey(String secretKey, Long currentTime, int time) {
    String key = String.valueOf(currentTime);
    try {
      String content = currentTime + secretKey + time;
      key = MD5Util.MD5Encode(content, "UTF-8");
//      log.info("当前MD5加密的结果：" + key);
    } catch (Exception e) {
      log.error("MD5加密失败！");
    }
    return key;
  }

  //TODO: 1.生成随机密钥 服务器用
  public static String generateSecretKey() throws NoSuchAlgorithmException {
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(Base64.decodeBase64(BASE64));
    byte[] buffer = sr.generateSeed(10);
    Base32 codec = new Base32();
    byte[] bEncodedKey = codec.encode(buffer);
    return new String(bEncodedKey);
  }

  /**
   * 十六进制转十进制.
   */
  public static int covert(String content) {
    int number = 0;
    String[] HighLetter = {"a", "b", "c", "d", "e", "f"};
    Map<String, Integer> map = new HashMap<>();
    for (int i = 0; i <= 9; i++) {
      map.put(i + "", i);
    }
    for (int j = 10; j < HighLetter.length + 10; j++) {
      map.put(HighLetter[j - 10], j);
    }
    String[] str = new String[content.length()];
    for (int i = 0; i < str.length; i++) {
      str[i] = content.substring(i, i + 1);
    }
    for (int i = 0; i < str.length; i++) {
      number += map.get(str[i]) * Math.pow(16, str.length - 1 - i);
    }
    return number;
  }
}
